package com.polaris.live.popup

import android.content.Context
import android.text.TextUtils
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.core.BottomPopupView
import com.polaris.live.R
import com.polaris.live.adapter.ContributionItemAdapter
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.ext.formatNumberWithK
import com.polaris.live.common.ext.overtime
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.network.requestLoading
import com.polaris.live.common.util.NavigationBarUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.constant.UserConst
import com.polaris.live.databinding.PopupContributionListBinding
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.net.userService
import com.polaris.live.resp.back_resp.Rank
import com.polaris.live.resp.back_resp.UserContributionRank
import com.polaris.live.utils.image.loadAvatar
import com.polaris.live.utils.state.UserStateUtils
import com.polaris.live.widget.UserStatusView
import com.polaris.live.widget.refresh.EmptyView

/**
 * ContributionListPopup
 * @author Created by 天晴 on 2024/5/28 16:26
 * @since 1.0.0
 **/
class ContributionListPopup(
    context: Context,
    private val mViewModel: BaseViewModel,
    private val anchorId: Long,
    private val data: UserContributionRank,
    private val toMessage: ((rank: Rank) -> Unit)?,
) :
    BottomPopupView(context) {

    private var day1: UserContributionRank? = null
    private var lastDay1: UserContributionRank? = null
    private var day7: UserContributionRank? = null
    private var day30: UserContributionRank? = null
    private var day1Time: Long = 0
    private var lastDay1Time: Long = 0
    private var day7Time: Long = 0
    private var day30Time: Long = 0

    private var isLastDay = false

    private val mAdapter by lazy {
        ContributionItemAdapter()
    }
    private val emptyView by lazy { EmptyView(context) }
    private var index = UserConst.ContributionStatus.DAY30 //ContributionStatus

    private lateinit var mBinding: PopupContributionListBinding

    override fun getImplLayoutId() = R.layout.popup_contribution_list

    override fun onCreate() {
        super.onCreate()
        mBinding = PopupContributionListBinding.bind(popupImplView)

        val lp = mBinding.bottom.layoutParams
        lp.height = NavigationBarUtils.getNavigationBarHeight(context)
        mBinding.bottom.layoutParams = lp

        day30 = data
        day30Time = System.currentTimeMillis()
        mBinding.root.setOnClickListener {
            //用于去除背景点击事件
        }

        mBinding.recycler.apply {
            adapter = mAdapter
            layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        }
        mAdapter.setEmptyView(emptyView)
        setIndex()
        updateUi(data)
        onListener()

        if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
            mBinding.todayBtn.setBackgroundResource(R.drawable.r16_ltb_f5f6fa)
        }

    }

    fun getData(@UserConst.ContributionType type: Int, last: Boolean = false) {
        getRankData(mViewModel, anchorId, type, last) {
            when (index) {
                UserConst.ContributionStatus.DAY1 -> {
                    if (isLastDay) {
                        lastDay1 = it
                        lastDay1Time = System.currentTimeMillis()
                    } else {
                        day1 = it
                        day1Time = System.currentTimeMillis()
                    }
                    updateUi(it)
                }

                UserConst.ContributionStatus.DAY7 -> {
                    day7 = it
                    day7Time = System.currentTimeMillis()
                    updateUi(it)
                }

                UserConst.ContributionStatus.DAY30 -> {
                    day30 = it
                    day30Time = System.currentTimeMillis()
                    updateUi(it)

                }
            }

        }

    }

    private fun clickDay1() {
        if (isLastDay) {
            if (lastDay1Time.overtime(OVERTIME) || lastDay1 == null) {
                getData(index, isLastDay)
            } else {
                lastDay1?.let {
                    updateUi(it)
                }
            }
        } else {
            if (day1Time.overtime(OVERTIME) || day1 == null) {
                getData(index, isLastDay)
            } else {
                day1?.let {
                    updateUi(it)
                }
            }
        }

    }

    private fun onListener() {
        mBinding.apply {
            close.setOnSingleClickListener {
                dismiss()
            }
            todayTv.setOnSingleClickListener {
                index = UserConst.ContributionStatus.DAY1
                isLastDay = false
                setIndex()
                clickDay1()
            }
            yesterdayTv.setOnSingleClickListener {
                index = UserConst.ContributionStatus.DAY1
                isLastDay = true
                setIndex()
                clickDay1()
            }
            day1Tv.setOnSingleClickListener {
                index = UserConst.ContributionStatus.DAY1
                setIndex()
                clickDay1()
            }
            day7Tv.setOnSingleClickListener {
                index = UserConst.ContributionStatus.DAY7
                setIndex()
                if (day7Time.overtime(OVERTIME) || day7 == null) {
                    getData(index)
                } else {
                    day7?.let {
                        updateUi(it)
                    }
                }
            }
            day30Tv.setOnSingleClickListener {
                index = UserConst.ContributionStatus.DAY30
                setIndex()
                if (day30Time.overtime(OVERTIME) || day30 == null) {
                    getData(index)
                } else {
                    day30?.let {
                        updateUi(it)
                    }

                }
            }

            top1Ll.setOnSingleClickListener {
                click(0)
            }
            top2Ll.setOnSingleClickListener {
                click(1)
            }
            top3Ll.setOnSingleClickListener {
                click(2)
            }

        }
        mAdapter.setOnItemClickListener { _, _, position ->
            click(position + 3)
        }
    }

    private fun click(position: Int) {
        //自己才能跳转
        if (anchorId != UserManager.getUserId()) {
            return
        }
        val data = when (index) {
            UserConst.ContributionStatus.DAY1 -> {
                if (isLastDay) {
                    lastDay1?.ranks?.getOrNull(position)
                } else {
                    day1?.ranks?.getOrNull(position)
                }
            }

            UserConst.ContributionStatus.DAY7 -> {
                day7?.ranks?.getOrNull(position)
            }

            UserConst.ContributionStatus.DAY30 -> {
                day30?.ranks?.getOrNull(position)
            }

            else -> {
                null
            }
        }
        data?.let { rank ->
            toMessage?.invoke(rank)
            dismiss()
        }
    }

    private fun setIndex() {
        resetUI()
        mBinding.apply {
            when (index) {
                UserConst.ContributionStatus.DAY1 -> {
                    day1Tv.setBackgroundResource(R.drawable.r60_back_ff5656_d10000)
                    day7Tv.setBackgroundResource(0)
                    day30Tv.setBackgroundResource(0)
                    todayBtn.visibility = View.VISIBLE
                    if (isLastDay) {
                        todayTv.setBackgroundResource(0)
                        yesterdayTv.setBackgroundResource(R.drawable.r20_back_000000_30)
                    } else {
                        todayTv.setBackgroundResource(R.drawable.r20_back_000000_30)
                        yesterdayTv.setBackgroundResource(0)

                    }
                }

                UserConst.ContributionStatus.DAY7 -> {
                    day1Tv.setBackgroundResource(0)
                    day7Tv.setBackgroundResource(R.drawable.r60_back_ff5656_d10000)
                    day30Tv.setBackgroundResource(0)
                    todayBtn.visibility = View.INVISIBLE
                }

                UserConst.ContributionStatus.DAY30 -> {
                    day1Tv.setBackgroundResource(0)
                    day7Tv.setBackgroundResource(0)
                    day30Tv.setBackgroundResource(R.drawable.r60_back_ff5656_d10000)
                    todayBtn.visibility = View.INVISIBLE
                }
            }
        }
    }

    private fun resetUI() {
        mBinding.apply {
            nameTop1.text = ""
            nameTop2.text = ""
            nameTop3.text = ""
            beansTvTop1.text = ""
            beansTvTop2.text = ""
            beansTvTop3.text = ""
            userCountry1.visibility = View.GONE
            userCountry2.visibility = View.GONE
            userCountry3.visibility = View.GONE
            levelView1.visibility = View.GONE
            levelView2.visibility = View.GONE
            levelView3.visibility = View.GONE
            vipView1.visibility = View.GONE
            vipView2.visibility = View.GONE
            vipView3.visibility = View.GONE
            avTop1.avatarTop.setImageResource(R.drawable.ic_default_avatar)
            avTop2.avatarTop.setImageResource(R.drawable.ic_default_avatar)
            avTop3.avatarTop.setImageResource(R.drawable.ic_default_avatar)
            mAdapter.setList(mutableListOf())
        }
    }

    private fun updateUi(data: UserContributionRank) {
        mBinding.apply {
            avTop1.vState.visibility = View.GONE
            avTop1.ivStateLive.visibility = View.GONE
            avTop2.vState.visibility = View.GONE
            avTop2.ivStateLive.visibility = View.GONE
            avTop3.vState.visibility = View.GONE
            avTop3.ivStateLive.visibility = View.GONE

            val top1User = data.ranks.getOrNull(0)
            top1User?.let {
                val nUser = it.user
                nameTop1.text = nUser.nickname
                beansTvTop1.text = it.score.formatNumberWithK()
                if (TextUtils.isEmpty(nUser.country)) {
                    userCountry1.visibility = View.GONE
                } else {
                    userCountry1.visibility = View.VISIBLE
                    userCountry1.setCountry(nUser.country)
                }
                vipView1.visibility = VISIBLE
                vipView1.setVipLevel(nUser.vipLevel)
                levelView1.setRichCharmBySexLevel(
                    nUser.sex,
                    nUser.richs,
                    nUser.charms
                )
                Glide.with(mBinding.root.context).loadAvatar(nUser.avatar).into(avTop1.avatarTop)
                stateShow(top1User.user, avTop1.vState, avTop1.ivStateLive)
            }
            val top2User = data.ranks.getOrNull(1)
            top2User?.let {
                val nUser = it.user
                nameTop2.text = nUser.nickname
                beansTvTop2.text = it.score.formatNumberWithK()
                if (TextUtils.isEmpty(nUser.country)) {
                    userCountry2.visibility = View.GONE
                } else {
                    userCountry2.visibility = View.VISIBLE
                    userCountry2.setCountry(nUser.country)
                }
                vipView2.visibility = VISIBLE
                vipView2.setVipLevel(nUser.vipLevel)
                levelView2.setRichCharmBySexLevel(
                    nUser.sex,
                    nUser.richs,
                    nUser.charms
                )
                Glide.with(mBinding.root.context).loadAvatar(nUser.avatar).into(avTop2.avatarTop)
                stateShow(top2User.user, avTop2.vState, avTop2.ivStateLive)
            }

            val top3User = data.ranks.getOrNull(2)
            top3User?.let {
                val nUser = it.user
                nameTop3.text = nUser.nickname
                beansTvTop3.text = it.score.formatNumberWithK()
                if (TextUtils.isEmpty(nUser.country)) {
                    userCountry3.visibility = View.GONE
                } else {
                    userCountry3.visibility = View.VISIBLE
                    userCountry3.setCountry(nUser.country)
                }
                vipView3.visibility = VISIBLE
                vipView3.setVipLevel(nUser.vipLevel)
                levelView3.setRichCharmBySexLevel(
                    nUser.sex,
                    nUser.richs,
                    nUser.charms
                )
                Glide.with(mBinding.root.context).loadAvatar(nUser.avatar).into(avTop3.avatarTop)
                stateShow(top3User.user, avTop3.vState, avTop3.ivStateLive)
            }
            if (data.ranks.size > 3) {
                mAdapter.setList(data.ranks.drop(3))
            }

        }
    }

    private fun stateShow(user: UserBasicVo, vState: View, ivStateLive: UserStatusView) {
        when (val state = UserStateUtils.resolveUserState(user)) {
            UserStateUtils.USER_STATE_ONLINE, UserStateUtils.USER_STATE_OFFLINE, UserStateUtils.USER_STATE_BUSY -> {
                vState.visibility = View.VISIBLE
                ivStateLive.visibility = View.GONE
                when (state) {
                    UserStateUtils.USER_STATE_ONLINE -> {
                        vState.setBackgroundResource(R.drawable.ic_user_space)
                    }

                    UserStateUtils.USER_STATE_OFFLINE -> {
                        vState.setBackgroundResource(R.drawable.shape_session_state_offline)
                    }

                    UserStateUtils.USER_STATE_BUSY -> {
                        vState.setBackgroundResource(R.drawable.shape_session_state_busy)
                    }

                    else -> {}
                }
            }

            UserStateUtils.USER_STATE_LIVE, UserStateUtils.USER_STATE_MATCH, UserStateUtils.USER_STATE_PARTY, UserStateUtils.USER_STATE_GAME -> {
                vState.visibility = View.GONE
                ivStateLive.visibility = View.VISIBLE
                when (state) {
                    UserStateUtils.USER_STATE_LIVE -> {
                        ivStateLive.setImageResource(null)
                    }

                    UserStateUtils.USER_STATE_MATCH -> {
                        ivStateLive.setImageResource(R.drawable.icon_list_match)
                    }

                    UserStateUtils.USER_STATE_PARTY -> {
                        ivStateLive.setImageResource(R.drawable.icon_party)
                    }

                    UserStateUtils.USER_STATE_GAME -> {
                        ivStateLive.setImageResource(R.drawable.icon_list_gameing)
                    }

                    else -> {}
                }
            }

            else -> {
                vState.visibility = View.GONE
                ivStateLive.visibility = View.GONE
            }
        }
    }

    companion object {

        const val OVERTIME: Long = 30 * 1000
        private var lastPop: BasePopupView? = null

        fun dismissPop() {
            lastPop?.dismiss()
            lastPop = null
        }

        fun showPop(
            context: Context,
            owner: LifecycleOwner,
            mViewModel: BaseViewModel,
            anchorId: Long,
            toMessage: ((rank: Rank) -> Unit)?,
        ) {
            owner.lifecycle.addObserver(object : LifecycleEventObserver {
                override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                    if (event == Lifecycle.Event.ON_DESTROY) {
                        dismissPop()
                    }
                }
            })
            dismissPop()
            getRankData(mViewModel, anchorId, UserConst.ContributionStatus.DAY30, false) {
                goPop(context, mViewModel, anchorId, it, toMessage)
            }
        }

        private fun goPop(
            context: Context,
            mViewModel: BaseViewModel,
            anchorId: Long,
            data: UserContributionRank,
            toMessage: ((rank: Rank) -> Unit)?,
        ) {
            lastPop = XPopup.Builder(context)
                .enableDrag(false)
                .dismissOnTouchOutside(true)
                .isDestroyOnDismiss(true)
                .asCustom(ContributionListPopup(context, mViewModel, anchorId, data, toMessage))
                .show()

        }

        fun getRankData(
            mViewModel: BaseViewModel,
            anchorId: Long,
            @UserConst.ContributionType rankType: Int,
            last: Boolean,
            back: (data: UserContributionRank) -> Unit,
        ) {
            mViewModel.requestLoading({
                userService.getRank(anchorId, rankType, last)
            }, {
                back.invoke(it)
            }, {
                ToastGravity.showGravity(it.errorMsg)
            })

        }

    }
}


